﻿using Abp.Application.Services.Dto;
using Abp.Auditing;
using Abp.AutoMapper;
using Abp.Domain.Repositories;
using Abp.UI;
using FutureApp.Shop.Dto;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;

namespace FutureApp.Shop
{
    /// <AppService/>
    [DisableAuditing]
    public class GoodsMouldAppService : FutureAppAppServiceBase, IGoodsMouldAppService
    {
        private IRepository<GoodsMould, Guid> GoodsMouldRepository { get; }
        private IRepository<GoodsMouldAssemble, Guid> GoodsMouldAssembleRepository { get; }

        /// <constructor/>
        public GoodsMouldAppService(
            IRepository<GoodsMould, Guid> goodsMouldRepository,
            IRepository<GoodsMouldAssemble, Guid> goodsMouldAssembleRepository
        )
        {
            this.GoodsMouldRepository = goodsMouldRepository;
            this.GoodsMouldAssembleRepository = goodsMouldAssembleRepository;
        }

        /// <inheritDoc/>
        public async Task<ListResultDto<GoodsMouldEntityDto>> GetGoodsMouldList()
        {
            var list = await this.GoodsMouldRepository.GetAllListAsync();
            return new ListResultDto<GoodsMouldEntityDto>(
                list.MapTo<List<GoodsMouldEntityDto>>()
                );
        }

        /// <inheritDoc/>
        public async Task<GoodsMouldEntityDto> GetGoodsMould(Guid id)
        {
            if (!await this.ExistGoodsMould(id))
                throw new UserFriendlyException(L("NotExistedGoodsMould"));
            var entity = await this.GoodsMouldRepository.GetAsync(id);
            return entity.MapTo<GoodsMouldEntityDto>();
        }

        /// <inheritDoc/>
        public async Task<GoodsMouldEntityDto> GetGoodsMould(string name)
        {
            if (!await this.ExistGoodsMould(name))
                throw new UserFriendlyException(L("NotExistedGoodsMould"));
            var entity = await this.GoodsMouldRepository.FirstOrDefaultAsync(e => e.Name == name);
            return entity.MapTo<GoodsMouldEntityDto>();
        }

        /// <inheritDoc/>
        public async Task<bool> ExistGoodsMould(Guid id)
        {
            var count = await this.GoodsMouldRepository.CountAsync(e => e.Id == id);
            return count != 0;
        }

        /// <inheritDoc/>
        public async Task<bool> ExistGoodsMould(string name)
        {
            var count = await this.GoodsMouldRepository.CountAsync(e => e.Name == name);
            return count != 0;
        }

        /// <inheritDoc/>
        public async Task CreateGoodsMould(CreateGoodsMouldInput input)
        {
            if (await this.ExistGoodsMould(input.Name))
                throw new UserFriendlyException(L("ExistedGoodsMouldName"));

            var entity = input.MapTo<GoodsMould>();
            entity = await this.GoodsMouldRepository.InsertAsync(entity);
            input.GoodsAttributes?.Select(val => new GoodsMouldAssemble { MouldId = entity.Id, AttibuteId = val })
                .ToList().ForEach(e => this.GoodsMouldAssembleRepository.InsertAsync(e));
        }

        /// <inheritDoc/>
        public async Task AssembleGoodsMould(AssembleGoodsMouldInput input)
        {
            if (!await this.ExistGoodsMould(input.GoodsMould))
                throw new UserFriendlyException(L("NotExistedGoodsMould"));
            await this.GoodsMouldAssembleRepository.DeleteAsync(e => e.MouldId == input.GoodsMould);
            input.GoodsAttributes?.Select(val => new GoodsMouldAssemble { MouldId = input.GoodsMould, AttibuteId = val })
                .ToList().ForEach(e => this.GoodsMouldAssembleRepository.InsertAsync(e));
        }

        /// <inheritDoc/>
        public async Task EnableGoodsMould(Guid id)
        {
            if (!await this.ExistGoodsMould(id))
                throw new UserFriendlyException(L("NotExistedGoodsMould"));
            var e = await this.GoodsMouldRepository.GetAsync(id);
            e.IsActive = true;
        }

        /// <inheritDoc/>
        public async Task DisableGoodsMould(Guid id)
        {
            if (!await this.ExistGoodsMould(id))
                throw new UserFriendlyException(L("NotExistedGoodsMould"));
            var e = await this.GoodsMouldRepository.GetAsync(id);
            e.IsActive = false;
        }
    }
}
